import 'dart:convert';

import 'package:aichat_flutter_wallet/module_common/bridge/bridge_bean.dart';
import 'package:aichat_flutter_wallet/module_common/provider/nav_key.dart';
import 'package:aichat_flutter_wallet/module_common/utils/task_code_to_flutter.dart';
import 'package:event_bus/event_bus.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:lib_database/lib_database.dart';
import 'package:lib_network/http_config.dart';
import 'package:aichat_flutter_wallet/kai_print.dart';
import 'package:lib_util/utils/utils.dart';

import '../../module/module_browser/viewmodel/before_browser.dart';
import '../widgets/dialog/password_auth_dialog.dart';

enum PageTypeNone {
  none, //0
  DApp, //1
  wallet, //2
  walletManager, //3
  walletCreatePassword, //4
}

EventBus eventBus = EventBus();

class ClickTabInEvent {
  AppCommMsg data;

  ClickTabInEvent(this.data);
}

class ControlDisplayPageEvent {
  String data;

  ControlDisplayPageEvent(this.data);
}

class ClickTabInEvent2 {
  AppCommMsg data;

  ClickTabInEvent2(this.data);
}
class GoBackEvent {
  bool data;

  GoBackEvent(this.data);
}
class GoShareSuccess {
  String data;

  GoShareSuccess(this.data);
}
class GoNativeScanResult {
  String data;

  GoNativeScanResult(this.data);
}

/**
 * 构建一个与原生通讯的bridge类
 */
class NativeChannelBridge {
  static final NativeChannelBridge instance = NativeChannelBridge._();

  factory NativeChannelBridge() => instance;
  static const method_controller_tab = "controller_tab"; //控制tab
  static const method_token_expire = "token_expire"; //token过期
  static const method_open_native_page = "open_native_page"; //打开原生页面
  static const channel_name = "com.kai.bitchat.bridge";
  static const platform = MethodChannel(channel_name);
  static const String method_set_user_msg = "set_user_msg"; //设置通用信息
  static const method_sendStoreReference =
      "sendStoreReference"; //发送数据库实例reference
  static const String method_close_flutterPage = "close_flutterPage";
  static const String method_did_open_page_type =
      "didOpenPageType"; //关闭整个flutter页面
  static const String method_googleAuth = "googleAuth"; //Google授权完成
  static const String method_appleAuth = "appleAuth"; //apple授权完成
  static const String method_getPublicAddress = "get_wallet_address"; //获取钱包地址
  static const String method_goBack = "goBack"; //安卓手势返回通知 flutter 返回上一页
  static const String method_goNewsBack = "goNewsBack"; //安卓手势返回通知 flutter 返回上一页
  static const String method_toStartPointsTask =
      "to_start_points_task"; //安卓手势返回通知 flutter 返回上一页
  static const String method_showPassWordDialog =
      "show_pass_dialog"; //安卓手势返回通知 flutter 返回上一页
  static const String method_h5CallNative =
      "h5_call_native"; //h5 调起 原生端 flutter 通道
  static const String method_sharePoster = "share_poster"; //分享图片
  // 新手任务 原生 调起 flutter 具体页面做 具体功能
  static const String method_NativeToFlutter = "native_to_flutter"; //分享图片
  // 点击wallet_tab
  static const String method_click_wallet_tab = 'click_wallet_tab';
  static const String method_FlDisplayPage = "display_page"; //分享图片
  static const String method_FlGoBrowser = "goBrowser"; //分享图片
  static const String method_FlGoComment = "go_comment"; //分享图片
  static const String method_FlGoCommentShare = "go_comment_share"; //分享图片
  static const String method_FlGoCommentSuccess = "go_operate_success"; //评论成功
  static const String method_FlPreviewMedia = "go_preview_media"; //评论成功
  static const String method_GoShareSuccess = "go_share_success"; //评论成功
  static const String method_NativeScanResult = "scan_result"; // native 扫码 消息推送
  static const String method_FlutterShowDialog = "show_flutter_dialog"; // native 扫码 消息推送

  NativeChannelBridge._() {}

  AppCommMsg? appCommMsg;

  void init() {
    //注册响应原生的调用监听
    platform.setMethodCallHandler((call) {
      /**
       * 监听原生android 或者ios 的调用
       */

      kaiPrint("call---------------${call}");
      if (call.method == method_set_user_msg) {
        //公共用户信息
        final argument = call.arguments as String;
        kaiPrint("set comm user success :$argument");
        try {
          var map = jsonDecode(argument);
          appCommMsg = AppCommMsg.fromJson({
            ...map['userMsg'],
            "page": map['page'],
            "parameter": map['parameter']
          });
          HttpConfig().headers = () {
            var headerParams={
              'Authorization': "${appCommMsg!.token}",
              "App-id": appCommMsg?.app_id,
              "channel": appCommMsg?.channel,
              "version-no": appCommMsg?.version_no,
            };
            if(appCommMsg?.enable_gray==true){
              headerParams["containers"] ='canary' ;
            }
            return headerParams;
          };
          if (['1', '2'].contains(appCommMsg!.appEnvType.toString())) {
            HttpConfig().isNeedCrypt = true;
          } else {
            // 初始化 不管
            HttpConfig().isNeedCrypt = false;
          }
          HttpConfig().baseURL = appCommMsg!.base_url;
          kaiPrint('HttpConfig().baseURL  ${HttpConfig().baseURL }');
          eventBus.fire(ClickTabInEvent(appCommMsg!));
        } catch (e) {
          kaiPrint("parse $method_set_user_msg fair:$e");
        }
        return Future.value("succeed");
      }

      if (call.method == method_NativeScanResult) {
        try {
          final argument = call.arguments;
          kaiPrint('method_NativeScanResult--flutter ${argument}');
          eventBus.fire(GoNativeScanResult(argument!));
          return Future.value("succeed");
        } catch (e) {
          return Future.value('fail');
        }
      }
      if (call.method == method_getPublicAddress) {
        final argument = call.arguments;
        try {
          var map = jsonDecode(argument);
          kaiPrint('getPublicAddress--flutter ${map}');
          var uid = map['userId'];
          getWalletAddress(uid);
          return Future.value("succeed");
        } catch (e) {
          return Future.value('fail');
        }
      }

      if (call.method == method_FlGoBrowser) {
        try {
          var map = jsonDecode(call.arguments);
          goBrowser(url: map['url']);
          return Future.value('succeed');
        } catch (e) {
          return Future.value(e.toString());
        }
      }
      // 监听原生 返回事件 让flutter 自己执行 返回
      if (call.method == method_goBack) {
        bool isLast = !Navigator.canPop(NavKey.getContext());
        if (!isLast) {
          Navigator.pop(NavKey.getContext());
          return Future.value("succeed");
        }
      }
      // 监听原生 返回事件 让flutter 自己执行 返回
      if (call.method == method_GoShareSuccess) {
        final argument = call.arguments;
        try{
          var data = jsonDecode(argument);
          eventBus.fire(GoShareSuccess(data['share_success'].toString()));
          return Future.value("succeed");
        }catch(e){
          return Future.value("failed");
        }
      }
      // 监听原生 返回事件 让flutter 自己执行 返回
      if (call.method == method_goNewsBack) {
        try{
          eventBus.fire(GoBackEvent(true));
          return Future.value("succeed");
        }catch(e){
          return Future.value("failed");
        }
      }

      if (call.method == method_NativeToFlutter) {
        final argument = call.arguments;
        try {
          kaiPrint('method_NativeToFlutter $argument');
          var taskCode = jsonDecode(argument);
          kaiPrint('taskCode ${taskCode["taskCode"].toString()}');
          TaskCodeToFlutter.linkToPage(taskCode["taskCode"].toString(), toAddress: taskCode['toAddress']??'');
          return Future.value("succeed");
        } catch (e) {
          return Future.value('fail');
        }
      }
      // 监听原生 返回事件 让flutter 弹出弹窗
      if (call.method == method_showPassWordDialog) {
        final argument = call.arguments;
        try {
          var map = jsonDecode(argument);
          kaiPrint('method_showPassWordDialog--flutter ${map}');
          // var uid = map['userId'];
          try {
            kaiPrint('Utils $Utils');
            kaiPrint('NavKey ${NavKey.getContext()}');
            Utils.showBottomSheetDialog(
                NavKey.getContext(),
                PasswordAuthDialog(
                  title: 'Please set a new password',
                )).then((value) {
              closeFlutterPage(num: 1);
            });
          } catch (e) {
            kaiPrint('=======================$e');
          }
          return Future.value("succeed");
        } catch (e) {
          return Future.value('fail');
        }
      }
      return Future.error("method not implement");
    });
  }

  AppCommMsg? parse(String argument) {
    kaiPrint("set comm user success :$argument");
    try {
      var map = jsonDecode(argument);
      // appCommMsg = AppCommMsg.fromJson(map);
      appCommMsg = AppCommMsg.fromJson({
        ...map['userMsg'],
        "page": map['page'],
        "parameter": map['parameter']
      });
    } catch (e) {
      kaiPrint("parse  AppCommMsg fair:$e");
    }
    return appCommMsg;
  }

  /**
   *
   * 控制tab的显示与不显示
   *
   */
  void controllerTabChange(bool show) async {
    try {
      Map<String, dynamic> map = {"tab_state": show ? 0 : 1};
      var json = jsonEncode(map);
      await platform.invokeMethod(method_controller_tab, json);
    } catch (e) {
      kaiPrint("controllerTabChange fair:$e");
    }
  }

  void getWalletAddress(String userId) async {
    try {
      kaiPrint('userId = $userId');
      // 等待 页面节点加载
      await Future.delayed(Duration(milliseconds: 300));
      if (userId.isEmpty) {
        throw Exception('userId isNotEmpty');
      }

      var wallet = await ObjectBox().walletModel.getWalletByUId(userId);
      if (wallet == null) {
        throw Exception("can't find wallet");
      }
      // 根据 链 生成 多个 在选择 链 中选中 即留下 存储 sp
      int currentWalletId = SP().getWalletSelectedInfoId(wallet.id);
      WalletInfo? walletInfo = null;
      if (currentWalletId != 0) {
        walletInfo =
            ObjectBox().walletInfoModel.getWalletInfoById(currentWalletId);
      } else {
        walletInfo = ObjectBox().walletInfoModel.getFirstWalletInfo(wallet);
      }
      if (walletInfo == null) {
        throw Exception("can't find walletInfo");
      }
      // 获取 当前 钱包 参数
      var address = walletInfo!.address;
      var chainLogo =
          walletInfo.getChain() != null ? walletInfo!.getChain()!.logo : '';
      Map<String, dynamic> map = {
        // 公钥地址
        "address": address,
        // 钱包余额
        'balance': walletInfo.balance ?? '0.00',
        // 链简称
        'chainShortName': walletInfo.chainShortName,
        // 链 logo
        'chainLogo': chainLogo,
        // 钱包状态
        'field': 'USDT',
      };
      var json = jsonEncode(map);
      kaiPrint('address = $address');

      platform.invokeMethod(method_getPublicAddress, json);
    } catch (e) {
      kaiPrint('address==$e');
      Map<String, dynamic> map = {};
      var json = jsonEncode(map);
      platform.invokeMethod(method_getPublicAddress, json);
    }
  }

  /**
   * token 过期
   */
  void tokenExpire() async {
    try {
      await platform.invokeMethod(method_token_expire);
    } catch (e) {
      kaiPrint("tokenExpire() fair:$e");
    }
  }

  /**
   * 打开原生的页面
   * path: 路由地址或者是外部浏览器的url
   * action: 0:在kai内部打开 1: 打开外部app
   */
  void openNativePage(String path, {int action = 0}) async {
    try {
      Map<String, dynamic> map = {"path": path, "action": action};
      var json = jsonEncode(map);
      await platform.invokeMethod(method_open_native_page, json);
    } catch (e) {
      kaiPrint("openNativePage() fair:$e");
    }
  }

  void sendReference(ByteData reference) async {
    try {
      var ref = reference.buffer.asUint8List();
      var str = '';
      for (int i = 0; i < ref.length; i++) {
        if (i != 0) {
          str += ',';
        }
        str += ref[i].toString();
      }

      Map<String, dynamic> map = {"reference": str};
      var json = jsonEncode(map);
      await platform.invokeMethod(method_sendStoreReference, json);
      kaiPrint('form flutter  reference to native ：${json}');
    } catch (e) {
      kaiPrint("sendReference() fair:$e");
    }
  }

  //
  void closeFlutterPage({int num = 0}) async {
    try {
      await platform.invokeMethod(method_close_flutterPage, num);
    } catch (e) {
      kaiPrint("closeFlutterPage() fair:$e");
    }
  }
  void flutterShowDialog({int num = 0}) async {
    try {
      String data = jsonEncode({'page': 'empty', "params": '{}'});
      await platform.invokeMethod(method_FlutterShowDialog, data);
    } catch (e) {
      kaiPrint("flutterShowDialog() fair:$e");
    }
  }

  void toStartPointsTask({int num = 0, String? uid}) async {
    try {
      await platform.invokeMethod(
          method_toStartPointsTask, jsonEncode({'taskCode': num, "uid": uid}));
    } catch (e) {
      kaiPrint("toStartPointsTask() fair:$e");
    }
  }

  void h5CallNative(String method, String params) async {
    try {
      String data = jsonEncode({'method': method, "params": params});
      await platform.invokeMethod(method_h5CallNative, data);
    } catch (e) {
      kaiPrint("h5CallNative() fair:$e");
    }
  }
  void flGoComment(String type, String id) async {
    try {
      String data = jsonEncode({'type': type, "id": id});
      await platform.invokeMethod(method_FlGoComment, data);
    } catch (e) {
      kaiPrint("h5CallNative() fair:$e");
    }
  }
  void flPreviewMedia({
    String type = 'image', String index= '1', List<String> datas = const [],
}) async {
    try {
      // {"type": "image",  index: 1, medals: }
      String data = jsonEncode({'type': type, "index": index, "datas": datas });
      await platform.invokeMethod(method_FlPreviewMedia, data);
    } catch (e) {
      kaiPrint("h5CallNative() fair:$e");
    }
  }

  void flGoCommentShare(String type, String id) async {
    try {
      String data = jsonEncode({'type': type, "id": id});
      await platform.invokeMethod(method_FlGoCommentShare, data);
    } catch (e) {
      kaiPrint("h5CallNative() fair:$e");
    }
  }
  // comment, like, forward, share, showPictures
  Future<String> flGoCommentSuccess(String type, String id, String action,{int? count}) async {
    try {
      String data = jsonEncode({'type': type, "id": id, "action" : action , "count": count??0 });
      return await platform.invokeMethod(method_FlGoCommentSuccess, data);
    } catch (e) {
      kaiPrint("h5CallNative() fair:$e");
      throw Exception('flGoCommentSuccess failed！');
    }
  }

  Future<bool> sharePoster(Uint8List? bytes) async {
    if (bytes == null) {
      kaiPrint("数据为空");
      return false;
    }
    try {
      await platform.invokeMethod(method_sharePoster, bytes);
      return true;
    } catch (e) {
      kaiPrint("h5CallNative() fair:$e");
      return false;
    }
  }
}
